package com.yakaten.service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import javax.transaction.UserTransaction;

import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.extension.jdbc.manager.JdbcManagerImpl;
import org.seasar.extension.jta.UserTransactionImpl;
import org.seasar.framework.beans.util.BeanMap;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.SingletonS2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
import org.seasar.framework.exception.ResourceNotFoundRuntimeException;

/**
 * データベース接続用クラス
 *
 * @author
 *
 */
public class JdbcManagerFactory {
	/**
	 * データベース接続、処理クラス。
	 */
	public static JdbcManager jdbcManager;

	/**
	 * データベース接続、処理クラス（自立型トランザクション用）。
	 */
	private static JdbcManager jdbcManagerNew;

	/**
	 * S2コンテナ
	 */
	private static S2Container container = null;

	/**
	 * クラス構造化
	 */
	public JdbcManagerFactory() {
		jdbcManager = getJdbcManager();
	}

	public static void main(String[] args) {
		String sql = "select * from kakaku_task";
		List<BeanMap> result = getJdbcManager().selectBySql(BeanMap.class, sql)
				.getResultList();
		for (BeanMap current : result) {
			System.out.println(current.get("kaisu"));
		}
	}

	/**
	 * JDBCマネージャ取得
	 *
	 * @return JDBCマネージャ
	 */
	public static synchronized JdbcManager getJdbcManager() {
		if (jdbcManager == null) {
			try {
				//for local ↓
//				S2ContainerFactory.configure("app.dicon");
//				S2Container container = S2ContainerFactory.getConfigurationContainer();
//
//				jdbcManager = (JdbcManager)container.getComponent(JdbcManager.class);

				//for server side ↓
				SingletonS2ContainerFactory.init();
				jdbcManager = SingletonS2Container
						.getComponent(JdbcManager.class);

			} catch (final ResourceNotFoundRuntimeException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return jdbcManager;
	}

	/**
	 * JDBCマネージャ取得（自立型トランザクション取得用）
	 *
	 * @return JDBCマネージャ
	 */
	public static synchronized JdbcManager getJdbcManagerNew() {
		return jdbcManagerNew;
	}

	/**
	 * JDBCコネクッションを取得します。<BR>
	 * クローズ処理は、各自で行って下さい。
	 *
	 * @return Connectionオブジェクト
	 * @throws SQLException
	 *             処理中に何らかの例外が発生した場合
	 */
	public static Connection getConnection() throws SQLException {
		if (jdbcManager == null) {
			getJdbcManager();
		}
		JdbcManagerImpl jdbcManagerImpl = (JdbcManagerImpl) jdbcManager;

		return jdbcManagerImpl.getDataSource().getConnection();
	}

	/**
	 * JDBCコネクッションのクローズ処理を行います。
	 *
	 * @param con
	 *            Connectionオブジェクト
	 */
	public static void close(final Connection con) {
		if (con == null) {
			return;
		}
		try {
			if (con.isClosed()) {
				return;
			}
			con.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * JTAリソース管理のS2コンテナを取得する
	 *
	 * @return S2Container
	 */
	public static S2Container getS2Container() {
		if (!SingletonS2ContainerFactory.hasContainer()) {
			container = S2ContainerFactory.create("app.dicon");
			container.init();
			SingletonS2ContainerFactory.setContainer(container);
		} else {
			container = SingletonS2ContainerFactory.getContainer();
		}
		return container;
	}

	/**
	 * ユーザトランザクション制御を生成する
	 *
	 * @return UserTransactionImpl
	 */
	public static UserTransactionImpl getUserTransaction() {
		if (jdbcManager == null) {
			getJdbcManager();
		}

		UserTransactionImpl ut = (UserTransactionImpl) container
				.getComponent(UserTransactionImpl.class);
		return ut;
	}

	/**
	 * ユーザトランザクション制御を生成する(自立型トランザクション用)
	 *
	 * @return ユーザートランザクション
	 */
	public static UserTransaction getUserTransactionNew() {
		S2Container container = S2ContainerFactory.create("app.dicon");
		container.init();
		jdbcManagerNew = (JdbcManager) container
				.getComponent(JdbcManager.class);
		return (UserTransaction) container
				.getComponent(UserTransactionImpl.class);
	}
}
